package com.siao.component
{
	import com.siao.display.LayoutElement;
	import com.siao.display.TooltipElement;
	
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.utils.Timer;
	
	/**
	 * 提示
	 * @author SiaoLeon
	 */
	public class Tooltip extends LayoutElement
	{
		// -------------------------------------------------------------------------------------------------------- 静态常量
		
		// -------------------------------------------------------------------------------------------------------- 静态变量
		
		// -------------------------------------------------------------------------------------------------------- 静态方法
		
		// -------------------------------------------------------------------------------------------------------- 静态函数
		
		// -------------------------------------------------------------------------------------------------------- 属性
		
		/**
		 * 显示时延迟时间，（单位：毫秒）
		 * @return
		 */
		public function get showDelay():Number
		{
			return this.showTimer.delay;
		}
		
		public function set showDelay(value:Number):void
		{
			this.showTimer.delay = value;
		}
		
		/**
		 * 隐藏时延迟时间，（单位：毫秒）
		 * @return
		 */
		public function get hideDelay():Number
		{
			return this.hideTimer.delay;
		}
		
		public function set hideDelay(value:Number):void
		{
			this.hideTimer.delay = value;
		}
		
		private var _displayMode:uint = TooltipsDisplayMode.MOUSE_DRAG;
		
		/**
		 * 显示模式
		 * @return
		 */
		public function get displayMode():uint
		{
			return this._displayMode;
		}
		
		public function set displayMode(value:uint):void
		{
			this._displayMode = value;
			
			this.init();
		}
		
		private var _element:TooltipElement;
		
		/**
		 * 目标元素
		 * @return
		 */
		public function get element():TooltipElement
		{
			return this._element;
		}
		
		public function set element(value:TooltipElement):void
		{
			if (this._element == value)
			{
				return;
			}
			
			if (this._element != null)
			{
				this._element.removeEventListener(Event.REMOVED_FROM_STAGE, onElementRemoved);
			}
			
			this._element = value;
			
			if (this.element == null)
			{
				return;
			}
			
			this._element.addEventListener(Event.REMOVED_FROM_STAGE, onElementRemoved, false, 0, true);
			
			this.onData(this.element.tooltipData);
		}
		
		// -------------------------------------------------------------------------------------------------------- 变量
		
		internal var container:DisplayObjectContainer;
		
		private var isMouseOver:Boolean;
		
		private var showTimer:Timer;
		
		private var hideTimer:Timer;
		
		// -------------------------------------------------------------------------------------------------------- 构造
		
		/**
		 * 构造函数
		 */
		public function Tooltip()
		{
			super();
			
			this.showTimer = new Timer(0, 1);
			this.hideTimer = new Timer(0, 1);
			
			this.showTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onShowTimerComplete, false, 0, true);
			this.hideTimer.addEventListener(TimerEvent.TIMER, onHideTimerComplete, false, 0, true);
		}
		
		// -------------------------------------------------------------------------------------------------------- 方法
		
		/**
		 * 显示
		 */
		public function show():void
		{
			if (this.hideTimer.running)
			{
				this.hideTimer.stop();
			}
			
			this.showTimer.reset();
			this.showTimer.start();
		}
		
		/**
		 * 隐藏
		 */
		public function hide():void
		{
			if (this.isMouseOver && this.displayMode != TooltipsDisplayMode.MOUSE_DRAG)
			{
				return;
			}
			
			if (this.showTimer.running)
			{
				this.showTimer.stop();
			}
			
			if (this.hideTimer.delay <= 0)
			{
				this.remove();
			}
			else
			{
				this.hideTimer.reset();
				this.hideTimer.start();
			}
		}
		
		// -------------------------------------------------------------------------------------------------------- 函数
		
		override protected function init():void
		{
			super.init();
			
			if (this.stage != null && this.displayMode == TooltipsDisplayMode.MOUSE_DRAG)
			{
				this.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true);
				
				this.position();
			}
			
			if (this.mouseEnabled)
			{
				this.addEventListener(MouseEvent.ROLL_OVER, onMouseOver, false, 0, true);
			}
		}
		
		override protected function exit():void
		{
			super.exit();
			
			if (this.stage != null)
			{
				this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				this.stage.removeEventListener(Event.MOUSE_LEAVE, onMouseOut);
			}
			
			this.removeEventListener(MouseEvent.ROLL_OVER, onMouseOver);
			this.removeEventListener(MouseEvent.ROLL_OUT, onMouseOut);
		}
		
		/**
		 * 更新数据时
		 * @param data
		 */
		protected function onData(data:Object):void
		{
		}
		
		/**
		 * 定位
		 */
		private function position():void
		{
			switch (this.displayMode)
			{
				case TooltipsDisplayMode.MOUSE:
				case TooltipsDisplayMode.MOUSE_DRAG:
					//鼠标跟随模式，X轴策略为舞台范围内，Y轴策略为鼠标下方不够显示则定位到鼠标上方
					var point:Point = this.parent.globalToLocal(new Point(this.stage.mouseX, this.stage.mouseY));
					var min:Point = new Point(0, 0);
					var max:Point = new Point(this.stage.stageWidth, this.stage.stageHeight);
					var x:Number = point.x + 15;
					var y:Number = (this.stage.mouseY + 20 + this.height > this.stage.stageHeight) ? point.y - this.offsetY - this.height - 5 : point.y + 20;
					
					this.x = Math.max(this.parent.globalToLocal(min).x - this.offsetX, Math.min(this.parent.globalToLocal(max).x - this.width - this.offsetX, x));
					this.y = Math.max(this.parent.globalToLocal(min).y - this.offsetY, Math.min(this.parent.globalToLocal(max).y - this.height - this.offsetY, y));
					
					break;
				
				default:
					break;
			}
		
		}
		
		/**
		 * 目标元素移除时
		 * @param event
		 */
		private function onElementRemoved(event:Event):void
		{
			this.remove();
		}
		
		/**
		 * 显示计时器完成时
		 * @param event
		 */
		private function onShowTimerComplete(event:TimerEvent):void
		{
			if (!this.container.contains(this))
			{
				this.container.addChild(this);
			}
		}
		
		/**
		 * 隐藏计时器完成时
		 * @param event
		 */
		private function onHideTimerComplete(event:TimerEvent):void
		{
			if (this.isMouseOver && this.displayMode != TooltipsDisplayMode.MOUSE_DRAG)
			{
				return;
			}
			
			if (this.container.contains(this))
			{
				this.remove();
			}
		}
		
		/**
		 * 鼠标移入时
		 * @param event
		 */
		private function onMouseOver(event:MouseEvent):void
		{
			this.isMouseOver = true;
			
			this.addEventListener(MouseEvent.ROLL_OUT, onMouseOut, false, 0, true);
			this.stage.addEventListener(Event.MOUSE_LEAVE, onMouseOut, false, 0, true);
		}
		
		/**
		 * 鼠标移出时
		 * @param event
		 */
		private function onMouseOut(event:MouseEvent):void
		{
			this.isMouseOver = false;
			this.hide();
			
			this.removeEventListener(MouseEvent.ROLL_OUT, onMouseOut);
			
			if (this.stage != null)
			{
				this.stage.removeEventListener(Event.MOUSE_LEAVE, onMouseOut);
			}
		}
		
		/**
		 * 鼠标移动时
		 * @param event
		 */
		private function onMouseMove(event:MouseEvent):void
		{
			if (this.element == null)
			{
				this.hide();
				return;
			}
			
			if (!this.hideTimer.running)
			{
				this.position();
			}
			
			event.updateAfterEvent();
		}
	
	}
}
